package com.dionysun.graphqlkickstart.extend;

import graphql.ExecutionResult;
import graphql.servlet.*;

import java.util.LinkedHashMap;
import java.util.Map;
import java.util.function.Supplier;

public class FdGraphQLObjectMapper extends GraphQLObjectMapper{

    protected FdGraphQLObjectMapper(Supplier<ObjectMapperConfigurer> objectMapperConfigurerSupplier, Supplier<GraphQLErrorHandler> graphQLErrorHandlerSupplier) {
        super(objectMapperConfigurerSupplier, graphQLErrorHandlerSupplier);
    }

    @Override
    public Map<String, Object> convertSanitizedExecutionResult(ExecutionResult executionResult, boolean includeData) {
        final Map<String, Object> result = new LinkedHashMap<>();
        if (includeData) {
            result.put("code", 200);
            result.put("data", executionResult.getData());
        }
        if (areErrorsPresent(executionResult)) {
            result.put("code", 500);
            result.put("errors", executionResult.getErrors());
        }
        if (executionResult.getExtensions() != null) {
            result.put("extensions", executionResult.getExtensions());
        }
        return result;
    }

    public static FdGraphQLObjectMapper.Builder newBuilder2() {
        return new FdGraphQLObjectMapper.Builder();
    }

    public static class Builder {
        private Supplier<ObjectMapperConfigurer> objectMapperConfigurer = DefaultObjectMapperConfigurer::new;
        private Supplier<GraphQLErrorHandler> graphQLErrorHandler = DefaultGraphQLErrorHandler::new;

        public FdGraphQLObjectMapper.Builder withObjectMapperConfigurer(ObjectMapperConfigurer objectMapperConfigurer) {
            return withObjectMapperConfigurer(() -> objectMapperConfigurer);
        }

        public FdGraphQLObjectMapper.Builder withObjectMapperConfigurer(Supplier<ObjectMapperConfigurer> objectMapperConfigurer) {
            this.objectMapperConfigurer = objectMapperConfigurer;
            return this;
        }

        public FdGraphQLObjectMapper.Builder withGraphQLErrorHandler(GraphQLErrorHandler graphQLErrorHandler) {
            return withGraphQLErrorHandler(() -> graphQLErrorHandler);
        }

        public FdGraphQLObjectMapper.Builder withGraphQLErrorHandler(Supplier<GraphQLErrorHandler> graphQLErrorHandler) {
            this.graphQLErrorHandler = graphQLErrorHandler;
            return this;
        }

        public FdGraphQLObjectMapper build() {
            return new FdGraphQLObjectMapper(objectMapperConfigurer, graphQLErrorHandler);
        }
    }

}
